////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016-2018 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxhwcontext.cpp
/// @brief HwContext class implementation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "camxhwcontext.h"
#include "camxhwenvironment.h"
#include "camxhwfactory.h"
#include "camximagesensormoduledata.h"
#include "camxincs.h"
#include "camxmem.h"
#include "camxpacket.h"

CAMX_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Static Methods
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::Create
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::Create(
    HwContextCreateData* pCreateData)
{
    CamxResult result = CamxResultEInvalidState;

    CAMX_ASSERT((NULL != pCreateData)                 &&
                (NULL != pCreateData->pHwEnvironment) &&
                (NULL != pCreateData->pHwEnvironment->GetHwStaticEntry()->Create));

    result = pCreateData->pHwEnvironment->GetHwStaticEntry()->Create(pCreateData);

    pCreateData->pHwContext->Initialize(pCreateData);

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::Initialize
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::Initialize(
    HwContextCreateData* pCreateData)
{
    CamxResult result = CamxResultEInvalidState;

    CAMX_ASSERT(NULL != pCreateData);

    m_pHwEnvironment = pCreateData->pHwEnvironment;
    result           = CSLOpen(&m_hCSLSession);

    CAMX_ASSERT_MESSAGE(CamxResultSuccess == result, "Failed to open CSL session");

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::Destroy
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID HwContext::Destroy()
{
    if (CSLInvalidHandle != m_hCSLSession)
    {
        CamxResult result = CSLClose(m_hCSLSession);
        CAMX_ASSERT(CamxResultSuccess == result);

        m_hCSLSession = CSLInvalidHandle;
    }

    m_pHwEnvironment = NULL;

    CAMX_DELETE this;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::~HwContext
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
HwContext::~HwContext()
{
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::Flush
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::Flush(
    BOOL bStart)
{
    CamxResult result = CamxResultSuccess;

    CAMX_ASSERT(CSLInvalidHandle != m_hCSLSession);

    if (CSLInvalidHandle != m_hCSLSession)
    {
        result = CSLFlush(m_hCSLSession, bStart);
    }
    else
    {
        result = CamxResultEInvalidState;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::FlushRequest
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::FlushRequest(
    CSLLinkHandle hLink,
    UINT64        requestId)
{
    CamxResult result = CamxResultSuccess;

    CAMX_ASSERT(CSLInvalidHandle != m_hCSLSession);

    if (CSLInvalidHandle != m_hCSLSession)
    {
        CAMX_LOG_INFO(CamxLogGroupCore, "Sending cancel request for requestId %llu", requestId);
        result = CSLCancelRequest(m_hCSLSession, hLink, requestId);
    }
    else
    {
        result = CamxResultEInvalidState;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::Link
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::Link(
    CSLLinkHandle*   phLink,
    CSLDeviceHandle* phDeviceHandles)
{
    CamxResult result = CamxResultSuccess;

    CAMX_ASSERT(CSLInvalidHandle != m_hCSLSession);

    if (CSLInvalidHandle != m_hCSLSession)
    {
        result = CSLLink(m_hCSLSession, phDeviceHandles, 0, phLink);
    }
    else
    {
        result = CamxResultEInvalidState;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::Unlink
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::Unlink(
    CSLLinkHandle*   phLink,
    CSLDeviceHandle* phDeviceHandles)
{
    CamxResult result = CamxResultSuccess;
    CAMX_UNREFERENCED_PARAM(phDeviceHandles);

    CAMX_ASSERT(CSLInvalidHandle != m_hCSLSession);

    if (CSLInvalidHandle != m_hCSLSession)
    {
        result = CSLUnlink(m_hCSLSession, phLink);
    }
    else
    {
        result = CamxResultEInvalidState;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::StreamOn
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::StreamOn(
    CSLLinkHandle*   phLink,
    CSLDeviceHandle* phDeviceHandles)
{
    CamxResult result = CamxResultSuccess;

    CAMX_ASSERT(CSLInvalidHandle != m_hCSLSession);

    if (CSLInvalidHandle != m_hCSLSession)
    {
        result = CSLStreamOn(m_hCSLSession, phLink, phDeviceHandles);
    }
    else
    {
        result = CamxResultEInvalidState;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::StreamOff
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::StreamOff(
    CSLLinkHandle*              phLink,
    CSLDeviceHandle*            phDeviceHandles,
    CHIDEACTIVATEPIPELINEMODE   mode)
{
    CamxResult result = CamxResultSuccess;

    CAMX_ASSERT(CSLInvalidHandle != m_hCSLSession);

    if (CSLInvalidHandle != m_hCSLSession)
    {
        result = CSLStreamOff(m_hCSLSession, phLink, phDeviceHandles, static_cast<CSLDeactivateMode>(mode));
    }
    else
    {
        result = CamxResultEInvalidState;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::Submit
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::Submit(
    CSLDeviceHandle hDevice,
    Packet*         pPacket)
{
    CamxResult result = CamxResultSuccess;

    CAMX_ASSERT(CSLInvalidHandle != m_hCSLSession);

    if (CSLInvalidHandle != m_hCSLSession)
    {
        result = CSLSubmit(m_hCSLSession, hDevice, pPacket->GetMemHandle(), pPacket->GetOffset());
    }
    else
    {
        result = CamxResultEInvalidState;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::GetImageSensorModuleData
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ImageSensorModuleData* HwContext::GetImageSensorModuleData(
    UINT32 cameraId
    ) const
{
    return m_pHwEnvironment->GetImageSensorModuleData(cameraId);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::GetDeviceVersion
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::GetDeviceVersion(
    CSLDeviceType   deviceType,
    CSLVersion*     pVersion
    ) const
{
    return m_pHwEnvironment->GetDeviceVersion(deviceType, pVersion);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::GetDriverVersion
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult HwContext::GetDriverVersion(
    CSLDeviceType   deviceType,
    CSLVersion*     pVersion
    ) const
{
    return m_pHwEnvironment->GetDriverVersion(deviceType, pVersion);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// HwContext::GetStaticSettings
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const StaticSettings* HwContext::GetStaticSettings()
{
    return m_pHwEnvironment->GetSettingsManager()->GetStaticSettings();
}


CAMX_NAMESPACE_END
